'''自制的用print打印表格的模块.解决不同字符长度不一的问题,这里的字符长度是
   ascii码小于256的1长度,其余的2长度.
   
   对外接口只有一个:
   printTable(table, header).
   table是要打印的[],每一项应为等长的[];
   header为[],指定标题与字符长度,格式,长度应与table的每一项相等,
     每一项为:[项目名, 字符长度, 格式化参数],格式化参数为例如'.3f'的字符串
   
   -----------------------
   last update @2020-06-14
   by setycyas
'''

def printTable(table, header):
  '''打印出指定的表table, 格式指定为header, 没有返回值
    参数:
    table: 要打印的表[],每一项为[],长度应相同.
    header: 表头与格式指定,长度应与table的每一项相同.每一项为:
      [项目名, 字符长度, 格式化参数],格式化参数为例如'.3f'的字符串,没有则用
      空字符串''
  '''
  string = '' # 每次打印的内容都储存在string中
  # 打印表头
  totalLength = 0
  for i in range(len(header)):
    head, length = header[i][0], header[i][1]
    string += _makeString(head, length, ' ')
    totalLength += length
  print(string)
  print('-'*totalLength)
  # 打印表内容
  for x in table:
    string = ''
    for i in range(len(x)):
      length, sFormat = header[i][1], header[i][2]
      string += _makeString(('{:'+sFormat+'}').format(x[i]), length, ' ')
    print(string)
  return
  
def _makeString(string, length, padding = '_', endPad = True):
  '''对给出的字符串,做成指定长度的新字符串,不足的长度用padding填充.
     注意汉字等ascii码>255的算2个长度.
     参数:
     string: 给定的字符串
     length: 指定长度
     padding: 填充不足长度的字符串
     endPad: True的时候,在字符串结尾填充,否则在开头填充
  '''
  totalLength = 0
  i = 0
  while(i < len(string)):
    char = string[i]
    charLength = 1
    if (ord(char) > 255):
      charLength = 2
    if (totalLength+charLength > length):
      break
    totalLength += charLength
    i += 1
  if endPad:
    result = string[0:i]+padding*(length-totalLength)
  else:
    result = padding*(length-totalLength)+string[0:i]
  return result


## 测试与使用实例  
if __name__ == '__main__':
  table = [
    ['张三', 15, 50.25869],
    ['李四', 30, 60.78961],
    ['王五', 105, 40.36253],
  ]
  header = [
    ['姓名(字符串测试)', 20, ''], 
    ['年龄(整数测试)', 20, ''],
    ['体重(浮点数测试)', 20, '.3f']
  ]
  printTable(table, header)
